package com.fbt.transfer.app.driver.baidu;

import android.annotation.SuppressLint;
import android.util.Log;
import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.fbt.transfer.app.driver.MyApplication;
import com.fbt.transfer.app.driver.util.LogUtils;
import com.fbt.transfer.app.driver.util.ZMToast;
import java.text.MessageFormat;

/**
 * 基于百度的GPS定位
 *
 * @author tuocoo
 * @create 2025-05-23
 * @since 1.0.0
 */
public class BaiDuLocationUtil {
  private static final String empty = "";
  // 定位服务是否使用中
  public transient boolean isWorking = false;
  public static volatile BDLocation locations;
  private static BaiDuLocationUtil mInstance;
  private static volatile LocationClient mLocationClient = null;
  /**
   * 定位点的省份
   */
  private static volatile String strLocationProvince;
  /**
   * 定位点的城市
   */
  private static volatile String strLocationCity;
  /**
   * 定位点的区县
   */
  private static volatile String strLocationDistrict;
  /**
   * 定位点的街道信息
   */
  private static volatile String strLocationStreet;
  /**
   * 定位点的街道号码
   */
  private static volatile String strLocationStreetNumber;
  /**
   * 定位点的详细地址(包括国家和以上省市区等信息)
   */
  private static volatile String strLocationAddrStr; 

  public static BaiDuLocationUtil getInstance() {
    if (mInstance == null) {
      synchronized (BaiDuLocationUtil.class) {
        if (mInstance == null) {
          mInstance = new BaiDuLocationUtil();
        }
      }
    }
    return mInstance;
  }

  /**
   * 是否是单次定位
   * @param isOnce true-单位定位 false-多次定位
   */
  public synchronized void startLocation(boolean isOnce) {
    LocationClientOption option = new LocationClientOption();
    // 可选，默认gcj02，设置返回的定位结果坐标系
    option.setCoorType("bd09ll");
    option.setAddrType("all");
    // 默认0，即仅定位一次，设置发起定位请求的间隔需要大于等于1000ms才是有效的
    option.setScanSpan(10 * 1000);
    // 设置定位模式：高精度，低功耗，仅设备，默认高精度
    option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
    // 可选，默认false,设置是否使用gps
    option.setOpenGps(true);
    // 返回的定位结果包含手机机头的方向
    option.setNeedDeviceDirect(true);
    // 可选，默认true，定位SDK内部是一个SERVICE，并放到了独立进程，设置是否在stop的时候杀死这个进程，默认不杀死
    option.setIgnoreKillProcess(true);
    // 可选，默认false，设置是否收集CRASH信息，默认收集
    option.SetIgnoreCacheException(true);
    option.setOnceLocation(isOnce);
    mLocationClient.setLocOption(option);
    if (!mLocationClient.isStarted()) {
      mLocationClient.start();
      Log.i("--> Location", " startLocation");
    }
    isWorking = true;
  }

  public synchronized void stopLocation() {
    Log.i("--> Location", " stopLocation");
    if (mLocationClient != null) {
      mLocationClient.stop();
    }
    // 定位服务是否使用中
    isWorking = false;
  }

  private BaiDuLocationUtil() {
    try {
      mLocationClient = new LocationClient(MyApplication.getApplication());
      mLocationClient.registerLocationListener(new BDLocationListener());
    } catch (Exception e) {
      LogUtils.e("InitLocationClient", "初始化位置定位失败", e);
    }
   
  }

  private class BDLocationListener extends BDAbstractLocationListener {
    private static final double SCALE_ = 4.9E-324;

    @SuppressLint("InvalidWakeLockTag")
    @Override
    public void onReceiveLocation(BDLocation location) {
      if (location == null
          || location.getLatitude() == SCALE_
          || location.getLongitude() == SCALE_) {
        Log.w("location", "未取到位置信息");
        return;
      }
      // 定位点地址信息做非空判断
      if (empty.equals(location.getProvince())) {
        strLocationProvince = "未知省";
      } else {
        strLocationProvince = location.getProvince();
      }
      if (empty.equals(location.getCity())) {
        strLocationCity = "未知市";
      } else {
        strLocationCity = location.getCity();
      }
      if (empty.equals(location.getDistrict())) {
        strLocationDistrict = "未知区";
      } else {
        strLocationDistrict = location.getDistrict();
      }
      if (empty.equals(location.getStreet())) {
        strLocationStreet = "未知街道";
      } else {
        strLocationStreet = location.getStreet();
      }
      if (empty.equals(location.getStreetNumber())) {
        strLocationStreetNumber = empty;
      } else {
        strLocationStreetNumber = location.getStreetNumber();
      }
      if (empty.equals(location.getAddrStr())) {
        strLocationAddrStr = empty;
      } else {
        strLocationAddrStr = location.getAddrStr();
      }
      double latitude = location.getLatitude();
      double longitude = location.getLongitude();
      // 定位成功后对获取的数据依据需求自定义处理，这里只做log显示
      LogUtils.d(
          "BDLocation",
          strLocationProvince
              + strLocationCity
              + strLocationDistrict
              + strLocationStreet
              + strLocationStreetNumber
              + strLocationAddrStr);
      locations = location;
      
     /* if (location.getLocType() == BDLocation.TypeGpsLocation || location.getLocType() == BDLocation.TypeNetWorkLocation) {
        BaiduNaviManagerFactory.getMapManager().getMapView().getMap().setMyLocationEnabled(true);
        BNLocationData locationData = new BNLocationData.Builder()
            .latitude(BaiDuLocationUtil.locations.getLatitude())
            .longitude(BaiDuLocationUtil.locations.getLongitude())
            .direction(BaiDuLocationUtil.locations.getDirection())
            .build();
        BaiduNaviManagerFactory.getMapManager().setMyLocationData(locationData);
        LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
        MapStatus.Builder builder = new MapStatus.Builder();
        builder.target(latLng).zoom(16.0f);
        BaiduNaviManagerFactory.getMapManager().getMapView().getMap().animateMapStatus(  MapStatusUpdateFactory.newMapStatus(builder.build()));
      }*/
      
      String latitudeStr = String.valueOf(latitude);
      String longitudeStr = String.valueOf(longitude);
      Log.i(
          "ZMLocation",
          MessageFormat.format(
              "百度定位，纬度:{0},经度:{1},方向:{2},速度:{3}",
              latitudeStr, longitudeStr, locations.getDirection(), locations.getSpeed()));
      UpLocationAsyncTask.execute(location);
    }

    @Override
    public void onConnectHotSpotMessage(String s, int i) {
      super.onConnectHotSpotMessage(s, i);
    }

    /**
     * 回调定位诊断信息，开发者可以根据相关信息解决定位遇到的一些问题 自动回调，相同的diagnosticType只会回调一次
     *
     * @param locType 当前定位类型
     * @param diagnosticType 诊断类型（1~9）
     * @param diagnosticMessage 具体的诊断信息释义、
     */
    @Override
    public void onLocDiagnosticMessage(int locType, int diagnosticType, String diagnosticMessage) {
      if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_BETTER_OPEN_GPS) // 建议打开GPS
      {

          LogUtils.w("--> Loc Diagnostic", "----------------> 建议打开GPS");

      } else if (diagnosticType
          == LocationClient.LOC_DIAGNOSTIC_TYPE_BETTER_OPEN_WIFI) // 建议打开wifi，不必连接，这样有助于提高网络定位精度！
      {
          LogUtils.w("--> Loc Diagnostic", "----------------> 建议打开wifi，不必连接，这样有助于提高网络定位精度！");

      } else if (diagnosticType
          == LocationClient
          .LOC_DIAGNOSTIC_TYPE_NEED_CHECK_LOC_PERMISSION) // 定位权限受限，建议提示用户授予APP定位权限！
      {
        ZMToast.info(MyApplication.getApplication(), "定位权限受限，请授予APP定位权限");

          LogUtils.w("--> Loc Diagnostic", "----------------> 定位权限受限，建议提示用户授予APP定位权限！");

      } else if (diagnosticType
          == LocationClient.LOC_DIAGNOSTIC_TYPE_NEED_CHECK_NET) // 网络异常造成定位失败，建议用户确认网络状态是否异常！
      {
          LogUtils.w("--> Loc Diagnostic", "----------------> 网络异常造成定位失败，建议用户确认网络状态是否异常！");

      } else if (diagnosticType
          == LocationClient
          .LOC_DIAGNOSTIC_TYPE_NEED_CLOSE_FLYMODE) // 手机飞行模式造成定位失败，建议用户关闭飞行模式后再重试定位！
      {
          LogUtils.w("--> Loc Diagnostic", "----------------> 手机飞行模式造成定位失败，建议用户关闭飞行模式后再重试定位！");

      } else if (diagnosticType
          == LocationClient
          .LOC_DIAGNOSTIC_TYPE_NEED_INSERT_SIMCARD_OR_OPEN_WIFI) // 无法获取任何定位依据，建议用户打开wifi或者插入sim卡重试！
      {
          LogUtils.w("--> Loc Diagnostic", "----------------> 无法获取任何定位依据，建议用户打开wifi或者插入sim卡重试！");

      } else if (diagnosticType
          == LocationClient
          .LOC_DIAGNOSTIC_TYPE_NEED_OPEN_PHONE_LOC_SWITCH) // 无法获取有效定位依据，建议用户打开手机设置里的定位开关后重试！
      {
          LogUtils.w("--> Loc Diagnostic", "----------------> 无法获取有效定位依据，建议用户打开手机设置里的定位开关后重试！");

      } else if (diagnosticType
          == LocationClient
          .LOC_DIAGNOSTIC_TYPE_SERVER_FAIL) // 百度定位服务端定位失败，建议反馈location.getLocationID()和大体定位时间到loc-bugs@baidu.com
      {
          LogUtils.w("--> Loc Diagnostic", "----------------> 百度定位服务端定位失败");

      } else if (diagnosticType
          == LocationClient
          .LOC_DIAGNOSTIC_TYPE_FAIL_UNKNOWN) // 无法获取有效定位依据，但无法确定具体原因，建议检查是否有安全软件屏蔽相关定位权限，或调用LocationClient.restart()重新启动后重试！
      {
          LogUtils.w("--> Loc Diagnostic", "----------------> 无法获取有效定位依据，但无法确定具体原因");
      }
    }
  }
}
